package com.yuanqi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuanqi.entity.*;
import com.yuanqi.mapper.*;
import com.yuanqi.service.WareTransferService;
import com.yuanqi.service.WareTransferItemService;
import com.yuanqi.service.InventoryService;
import com.yuanqi.service.InventoryTxnService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.*;

/**
* @author HP
* @description 针对表【ware_transfer(库存调拨单)】的数据库操作Service实现
* @createDate 2025-08-28 16:00:00
*/
@Slf4j
@Service
public class WareTransferServiceImpl extends ServiceImpl<WareTransferMapper, WareTransfer>
    implements WareTransferService {

    @Autowired
    private WareTransferItemService wareTransferItemService;
    
    @Autowired
    private InventoryService inventoryService;
    
    @Autowired
    private InventoryTxnService inventoryTxnService;

    @Override
    public IPage<WareTransfer> listTransfers(Integer page, Integer size, String transferCode, 
                                           Long fromWarehouseId, Long toWarehouseId, String transferType, Integer status) {
        Page<WareTransfer> pageParam = new Page<>(page, size);
        
        LambdaQueryWrapper<WareTransfer> queryWrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(transferCode)) {
            queryWrapper.like(WareTransfer::getTransferCode, transferCode);
        }
        if (fromWarehouseId != null) {
            queryWrapper.eq(WareTransfer::getFromWarehouseId, fromWarehouseId);
        }
        if (toWarehouseId != null) {
            queryWrapper.eq(WareTransfer::getToWarehouseId, toWarehouseId);
        }
        if (StringUtils.hasText(transferType)) {
            queryWrapper.eq(WareTransfer::getTransferType, transferType);
        }
        if (status != null) {
            queryWrapper.eq(WareTransfer::getStatus, status);
        }
        
        queryWrapper.orderByDesc(WareTransfer::getCreatedAt);
        
        return this.page(pageParam, queryWrapper);
    }

    @Override
    public Map<String, Object> getTransferDetail(Long id) {
        Map<String, Object> result = new HashMap<>();
        
        // 获取调拨单基本信息
        WareTransfer transfer = this.getById(id);
        result.put("transfer", transfer);
        
        // 获取调拨明细
        List<WareTransferItem> items = wareTransferItemService.getItemsByTransferId(id);
        result.put("items", items);
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createTransfer(WareTransfer transfer, List<WareTransferItem> items) {
        try {
            // 设置默认值
            if (transfer.getStatus() == null) {
                transfer.setStatus(0); // 新建状态
            }
            if (transfer.getCreatedAt() == null) {
                transfer.setCreatedAt(new Date());
            }
            
            // 保存调拨单
            boolean saved = this.save(transfer);
            if (!saved) {
                log.error("保存调拨单失败: {}", transfer);
                return false;
            }
            
            // 保存调拨明细
            if (items != null && !items.isEmpty()) {
                for (WareTransferItem item : items) {
                    item.setTransferId(transfer.getId());
                    // 计算总金额
                    if (item.getQty() != null && item.getUnitPrice() != null) {
                        item.setTotalAmount(item.getQty().multiply(item.getUnitPrice()));
                    }
                }
                boolean itemsSaved = wareTransferItemService.saveItems(items);
                if (!itemsSaved) {
                    log.error("保存调拨明细失败: {}", items);
                    throw new RuntimeException("保存调拨明细失败");
                }
            }
            
            log.info("创建调拨单成功: {}", transfer.getTransferCode());
            return true;
        } catch (Exception e) {
            log.error("创建调拨单失败: {}", e.getMessage(), e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTransfer(WareTransfer transfer, List<WareTransferItem> items) {
        try {
            // 检查状态，只有新建和已驳回状态才能修改
            WareTransfer existingTransfer = this.getById(transfer.getId());
            if (existingTransfer == null) {
                log.error("调拨单不存在: {}", transfer.getId());
                return false;
            }
            
            if (existingTransfer.getStatus() != 0 && existingTransfer.getStatus() != 4) {
                log.error("调拨单状态不允许修改: status={}", existingTransfer.getStatus());
                return false;
            }
            
            // 更新调拨单
            boolean updated = this.updateById(transfer);
            if (!updated) {
                log.error("更新调拨单失败: {}", transfer);
                return false;
            }
            
            // 删除原有明细
            wareTransferItemService.deleteItemsByTransferId(transfer.getId());
            
            // 保存新明细
            if (items != null && !items.isEmpty()) {
                for (WareTransferItem item : items) {
                    item.setTransferId(transfer.getId());
                    item.setId(null); // 确保是新记录
                    // 计算总金额
                    if (item.getQty() != null && item.getUnitPrice() != null) {
                        item.setTotalAmount(item.getQty().multiply(item.getUnitPrice()));
                    }
                }
                boolean itemsSaved = wareTransferItemService.saveItems(items);
                if (!itemsSaved) {
                    log.error("保存调拨明细失败: {}", items);
                    throw new RuntimeException("保存调拨明细失败");
                }
            }
            
            log.info("更新调拨单成功: {}", transfer.getTransferCode());
            return true;
        } catch (Exception e) {
            log.error("更新调拨单失败: {}", e.getMessage(), e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitForAudit(Long id) {
        try {
            WareTransfer transfer = this.getById(id);
            if (transfer == null) {
                log.error("调拨单不存在: {}", id);
                return false;
            }
            
            if (transfer.getStatus() != 0 && transfer.getStatus() != 4) {
                log.error("调拨单状态不允许提交审核: status={}", transfer.getStatus());
                return false;
            }
            
            transfer.setStatus(1); // 待审核状态
            boolean updated = this.updateById(transfer);
            
            if (updated) {
                log.info("调拨单提交审核成功: {}", transfer.getTransferCode());
            }
            
            return updated;
        } catch (Exception e) {
            log.error("提交审核失败: {}", e.getMessage(), e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean approveTransfer(Long id, String approvedBy) {
        try {
            WareTransfer transfer = this.getById(id);
            if (transfer == null) {
                log.error("调拨单不存在: {}", id);
                return false;
            }
            
            if (transfer.getStatus() != 1) {
                log.error("调拨单状态不允许审核通过: status={}", transfer.getStatus());
                return false;
            }
            
            transfer.setStatus(2); // 已审核状态
            transfer.setApprovedBy(approvedBy);
            transfer.setApprovedAt(new Date());
            
            boolean updated = this.updateById(transfer);
            
            if (updated) {
                log.info("调拨单审核通过成功: {}", transfer.getTransferCode());
            }
            
            return updated;
        } catch (Exception e) {
            log.error("审核通过失败: {}", e.getMessage(), e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean rejectTransfer(Long id, String approvedBy) {
        try {
            WareTransfer transfer = this.getById(id);
            if (transfer == null) {
                log.error("调拨单不存在: {}", id);
                return false;
            }
            
            if (transfer.getStatus() != 1) {
                log.error("调拨单状态不允许审核驳回: status={}", transfer.getStatus());
                return false;
            }
            
            transfer.setStatus(4); // 已驳回状态
            transfer.setApprovedBy(approvedBy);
            transfer.setApprovedAt(new Date());
            
            boolean updated = this.updateById(transfer);
            
            if (updated) {
                log.info("调拨单审核驳回成功: {}", transfer.getTransferCode());
            }
            
            return updated;
        } catch (Exception e) {
            log.error("审核驳回失败: {}", e.getMessage(), e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completeTransfer(Long id, String completedBy) {
        try {
            WareTransfer transfer = this.getById(id);
            if (transfer == null) {
                log.error("调拨单不存在: {}", id);
                return false;
            }
            
            if (transfer.getStatus() != 2) {
                log.error("调拨单状态不允许完成: status={}", transfer.getStatus());
                return false;
            }
            
            // 获取调拨明细
            List<WareTransferItem> items = wareTransferItemService.getItemsByTransferId(id);
            
            // 执行库存调拨
            for (WareTransferItem item : items) {
                // 从调出仓库减少库存
                boolean outResult = inventoryService.decreaseInventory(
                    transfer.getFromWarehouseId(), 
                    item.getSkuId(), 
                    item.getQty(), 
                    item.getBatchNo()
                );
                
                if (!outResult) {
                    log.error("调出仓库库存不足: warehouseId={}, skuId={}, qty={}", 
                             transfer.getFromWarehouseId(), item.getSkuId(), item.getQty());
                    throw new RuntimeException("调出仓库库存不足");
                }
                
                // 向调入仓库增加库存
                boolean inResult = inventoryService.increaseInventory(
                    transfer.getToWarehouseId(), 
                    item.getSkuId(), 
                    item.getQty(), 
                    item.getBatchNo(),
                    item.getExpiryDate()
                );
                
                if (!inResult) {
                    log.error("调入仓库库存增加失败: warehouseId={}, skuId={}, qty={}", 
                             transfer.getToWarehouseId(), item.getSkuId(), item.getQty());
                    throw new RuntimeException("调入仓库库存增加失败");
                }
                
                // 记录库存交易
                InventoryTxn outTxn = new InventoryTxn();
                outTxn.setTxnCode("TXN" + System.currentTimeMillis() + "_OUT");
                outTxn.setWarehouseId(transfer.getFromWarehouseId());
                outTxn.setLocationId(1L); // 设置默认库位ID
                outTxn.setSkuId(item.getSkuId());
                outTxn.setTxnType("TRANSFER_OUT");
                outTxn.setQty(item.getQty().negate()); // 负数表示出库
                outTxn.setBatchNo(item.getBatchNo());
                outTxn.setReferenceTable("ware_transfer");
                outTxn.setReferenceId(transfer.getId());
                outTxn.setRemark("调拨出库");
                outTxn.setCreatedAt(new Date());
                inventoryTxnService.save(outTxn);
                
                InventoryTxn inTxn = new InventoryTxn();
                inTxn.setTxnCode("TXN" + System.currentTimeMillis() + "_IN");
                inTxn.setWarehouseId(transfer.getToWarehouseId());
                inTxn.setLocationId(1L); // 设置默认库位ID
                inTxn.setSkuId(item.getSkuId());
                inTxn.setTxnType("TRANSFER_IN");
                inTxn.setQty(item.getQty()); // 正数表示入库
                inTxn.setBatchNo(item.getBatchNo());
                inTxn.setReferenceTable("ware_transfer");
                inTxn.setReferenceId(transfer.getId());
                inTxn.setRemark("调拨入库");
                inTxn.setCreatedAt(new Date());
                inventoryTxnService.save(inTxn);
            }
            
            // 更新调拨单状态
            transfer.setStatus(3); // 已完成状态
            transfer.setCompletedBy(completedBy);
            transfer.setCompletedAt(new Date());
            
            boolean updated = this.updateById(transfer);
            
            if (updated) {
                log.info("调拨单完成成功: {}", transfer.getTransferCode());
            }
            
            return updated;
        } catch (Exception e) {
            log.error("完成调拨失败: {}", e.getMessage(), e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteTransfer(Long id) {
        try {
            WareTransfer transfer = this.getById(id);
            if (transfer == null) {
                log.error("调拨单不存在: {}", id);
                return false;
            }
            
            if (transfer.getStatus() != 0) {
                log.error("调拨单状态不允许删除: status={}", transfer.getStatus());
                return false;
            }
            
            // 删除明细
            wareTransferItemService.deleteItemsByTransferId(id);
            
            // 删除调拨单
            boolean deleted = this.removeById(id);
            
            if (deleted) {
                log.info("删除调拨单成功: {}", transfer.getTransferCode());
            }
            
            return deleted;
        } catch (Exception e) {
            log.error("删除调拨单失败: {}", e.getMessage(), e);
            throw e;
        }
    }
}